﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework;

namespace ZoambieGaem {
    class Draw {

        public void update(Master m, SpriteBatch spriteBatch, PrimitiveBatch primitiveBatch) {

            spriteBatch.Begin();
            drawGround(m, spriteBatch);
            drawBlood(m, spriteBatch);
            drawEnemies(m, spriteBatch);
            drawPlayer(m, spriteBatch);
            drawRouteMap(m, spriteBatch);
            drawProjectile(m, spriteBatch);
            drawWalls(m, spriteBatch);
            drawWeapon(m, spriteBatch);
            //drawFlashlight(m, spriteBatch);
            spriteBatch.End();

            if (m.drawShadows)
                drawShadows(m, primitiveBatch);
            
            spriteBatch.Begin();
            drawDebug(m, spriteBatch);
            spriteBatch.End();

            FPS(m);
        }






        private void drawRouteMap(Master m, SpriteBatch sb) {
            for (int y = 0; y < Maps.height; y++) {
                for (int x = 0; x < Maps.width; x++) {
                    if (m.routeMap[y][x] < 99999) {
                        String value = "" + m.routeMap[y][x];

                        int xp = (int)(-m.player.worldPosition.X - (m.mouseFollower.X - m.screenWidth) + (x * m.blockSize));
                        int yp = (int)(-m.player.worldPosition.Y - (m.mouseFollower.Y - m.screenHeight) + (y * m.blockSize));
                        sb.DrawString(m.font, value, new Vector2(xp, yp), Color.White);
                    }
                }
            }
        }



        private void drawBlood(Master m, SpriteBatch sb) {
            try {
                lock (m.bloodList) {
                    foreach (Blood b in m.bloodList) {
                        try {
                            lock (b) {
                                int xp = (int)(-m.player.worldPosition.X - (m.mouseFollower.X - m.screenWidth) + (b.worldPosition.X));
                                int yp = (int)(-m.player.worldPosition.Y - (m.mouseFollower.Y - m.screenHeight) + (b.worldPosition.Y));
                                Vector2 pos = new Vector2(xp, yp);
                                Texture2D blod = m.zombieBloodTexture;
                                if (b.type == 0)
                                    blod = m.playerBloodTexture;
                                if (b.type == 1)
                                    blod = m.zombieBloodTexture;
                                sb.Draw(blod,
                                     pos,
                                     null,                  //Ei vielä animointia
                                     b.color,
                                     b.drawAngle,
                                     new Vector2(b.centerX, b.centerY),
                                     (m.drawScale * b.size),
                                     SpriteEffects.None,
                                     1);
                            }
                        }
                        catch (Exception e) { Console.WriteLine("BLOOD DRAW FAILURE " + e); };
                    }
                }
            }
            catch (Exception e) { Console.WriteLine("BLOOD DRAW MAJOR FAILURE " + e); };
        }
        



        private void drawPlayer(Master m, SpriteBatch sb) {
            lock (m.player) {
                float left = -(m.mouseFollower.X - m.screenWidth);
                float top = -(m.mouseFollower.Y - m.screenHeight);
                Vector2 pos = new Vector2(left, top);
                m.player.screenPosition = pos;
                sb.Draw(m.player.texture,
                         pos,
                         null,                  //Ei vielä animointia
                         Color.White,
                         m.player.angle,
                         new Vector2(m.player.centerX, m.player.centerY),
                         m.drawScale,
                         SpriteEffects.None,
                         1);
            }
        }


        private void drawFlashlight(Master m, SpriteBatch sb) {
            float left = -(m.mouseFollower.X - m.screenWidth);
            float top = -(m.mouseFollower.Y - m.screenHeight);
            Vector2 pos = new Vector2(left, top);
            sb.Draw(m.flashlight.texture,
                     m.player.screenPosition,
                     null,                  //Ei vielä animointia
                     Color.Black,
                     m.player.angle,
                     new Vector2(210, 240),
                     2f,
                     SpriteEffects.None,
                     1);
            //sb.Draw(m.range, new Rectangle((int)m.player.screenPosition.X - 512, (int)m.player.screenPosition.Y - 512, 1024,1024), new Color(1f,1f,1f,0.75f));
        }




        private void drawDebug(Master m, SpriteBatch sb) {
            String debug1 = "P-worldPos: " + (int)m.player.worldPosition.X + " " + (int)m.player.worldPosition.Y;
            String debug0 = "P-screenPos: " + (int)m.player.screenPosition.X + " " + (int)m.player.screenPosition.Y;
            String debug2 = "ScreenReso: " + m.screenWidth + " " + +m.screenHeight;
            String debug3 = "Mouse: " + m.mouse.X + " " + m.mouse.Y;
            String debug7 = "CameraPos: " + (int)m.mouseFollower.X + " " + (int)m.mouseFollower.Y;
            String debug4 = "FPS: " + m.FPS;
            String debug5 = "MapDrawSize: " + m.blockSize;
            String debug6 = "P-DrawSize: " + m.drawScale;
            String debug8 = "Zoambies: " + m.zoambieList.Count();

            String info1 = "PRESS Q TO TOGGLE SHADOWS";
            String info2 = "PRESS ESC TO EXIT";

            sb.DrawString(m.font, debug1, new Vector2(10, 10), Color.White);
            sb.DrawString(m.font, debug0, new Vector2(10, 30), Color.White);
            sb.DrawString(m.font, debug2, new Vector2(10, 50), Color.White);
            sb.DrawString(m.font, debug3, new Vector2(10, 70), Color.White);
            sb.DrawString(m.font, debug7, new Vector2(10, 90), Color.White);
            sb.DrawString(m.font, debug5, new Vector2(10, 110), Color.White);
            sb.DrawString(m.font, debug6, new Vector2(10, 130), Color.White);
            sb.DrawString(m.font, debug8, new Vector2(10, 150), Color.White);

            sb.DrawString(m.font, debug4, new Vector2(10, 190), Color.White);

            sb.DrawString(m.font, info1, new Vector2(10, 300), Color.White);
            sb.DrawString(m.font, info2, new Vector2(10, 320), Color.White);


        }

        private void drawWeapon(Master m, SpriteBatch sb)
        {
            int xp = (int)(-m.player.worldPosition.X - (m.mouseFollower.X - m.screenWidth) + m.player.width);
            int yp = (int)(-m.player.worldPosition.Y - (m.mouseFollower.Y - m.screenHeight) + m.player.height);

            Vector2 pos = new Vector2(xp, yp);
            Rectangle spriterect = new Rectangle(100, 0, 50, 40);
            sb.Draw(m.sawTexture,
                     pos,
                     spriterect,
                     Color.White,
                     m.player.angle,
                     new Vector2(m.player.centerX, m.player.centerY),
                     m.drawScale,
                     SpriteEffects.None,
                     1);
        }



        private void drawEnemies(Master m, SpriteBatch sb) {
            Rectangle spriterect;
            try {
                
                lock (m.deadzoambieList) {
                    //Draw dead zoambies first to avoid dead zoambie sprites overlapping live ones.

                    foreach (Zoambie z in m.deadzoambieList) {
                        lock (z) {
                            {
                                int xp = (int)(-m.player.worldPosition.X - (m.mouseFollower.X - m.screenWidth) + (z.worldPosition.X));
                                int yp = (int)(-m.player.worldPosition.Y - (m.mouseFollower.Y - m.screenHeight) + (z.worldPosition.Y));
                                z.transparency -= 0.10f;

                                if (z.transparency <= 1)
                                {
                                    m.deadzoambieList.Remove(z);
                                }

                                else
                                {
                                    Vector2 pos = new Vector2(xp, yp);
                                    spriterect = new Rectangle(100, 0, 100, 100);
                                    //z.color = new Color(255, 255, 255, z.transparency);
                                    z.color = Color.FromNonPremultiplied(0, 200, 0, (int)z.transparency);
                                    sb.Draw(z.texture,
                                             pos,
                                             spriterect,
                                             z.color,
                                             z.angle,
                                             new Vector2(z.centerX, z.centerY),
                                             m.drawScale,
                                             SpriteEffects.None,
                                             1);
                                }
                            }
                        }
                    }
                }
                }
            catch (Exception e) {
                Console.WriteLine("DEAD ZOMBIE DRAW FAILED " + e);

            }
            try {

                lock (m.zoambieList) {
                    foreach (Zoambie z in m.zoambieList) {
                        lock (z) {
                            spriterect = new Rectangle(0, 0, 100, 100);
                            if (z != null) {
                                int xp = (int)(-m.player.worldPosition.X - (m.mouseFollower.X - m.screenWidth) + (z.worldPosition.X));
                                int yp = (int)(-m.player.worldPosition.Y - (m.mouseFollower.Y - m.screenHeight) + (z.worldPosition.Y));
                                Vector2 pos = new Vector2(xp, yp);
                                sb.Draw(z.texture,
                                     pos,
                                     spriterect,
                                     Color.White,
                                     z.angle,
                                     new Vector2(z.centerX, z.centerY),
                                     m.drawScale,
                                     SpriteEffects.None,
                                     1);
                            }
                        }
                    }
                }
            }
            catch (Exception e) {
                Console.WriteLine("ZOMBIE DRAW FAILED " + e);

            }
        }
        
        
        private void drawProjectile(Master m, SpriteBatch sb) {
            try {
                lock (m.projectileList) {
                    foreach (Projectile p in m.projectileList) {
                        lock (p) {
                            int xp = (int)(-m.player.worldPosition.X - (m.mouseFollower.X - m.screenWidth) + (p.worldPosition.X));
                            int yp = (int)(-m.player.worldPosition.Y - (m.mouseFollower.Y - m.screenHeight) + (p.worldPosition.Y));
                            Vector2 pos = new Vector2(xp, yp);

                            sb.Draw(Weapons.getProjectileTexture(p.type),
                                     pos,
                                     null,                  //Ei vielä animointia
                                     Color.FromNonPremultiplied(255, 255, 255, 200),
                                     p.angle,
                                     new Vector2(p.centerX, p.centerY),
                                     1,
                                     SpriteEffects.None,
                                     1);
                        }
                    }
                }
            }
            catch (Exception e) { Console.WriteLine("PROJECTILE DRAW FAILED " + e); }
        }
        

        


        private void drawGround(Master m, SpriteBatch sb) {
            /*
            int xp = 0;
            int yp = 0;
            for (int y = 0; y < Maps.height; y++) {
                for (int x = 0; x < Maps.width; x++) {
                    //int block = m.map[y][x];
                    //MAA
                    //if (block == 0 || block == 2) {
                        xp = (int)(-m.player.worldPosition.X - (m.mouseFollower.X - m.screenWidth) + (x * m.blockSize));
                        yp = (int)(-m.player.worldPosition.Y - (m.mouseFollower.Y - m.screenHeight) + (y * m.blockSize));

                        sb.Draw(m.ground, new Rectangle(xp, yp, m.blockSize, m.blockSize), Color.White);
                    //}
                }
            }
             */
            int xp = (int)(-m.player.worldPosition.X - (m.mouseFollower.X - m.screenWidth) + 0);
            int yp = (int)(-m.player.worldPosition.Y - (m.mouseFollower.Y - m.screenHeight) + 0);
            sb.Draw(m.ground, new Rectangle(xp, yp, Maps.width*m.blockSize, Maps.height * m.blockSize), Color.White);
        }




        private void drawWalls(Master m, SpriteBatch sb) {
            int xp = 0;
            int yp = 0;
            for (int y = 0; y < Maps.height; y++) {
                for (int x = 0; x < Maps.width; x++) {
                    int block = m.map[y][x];
                    //SEINÄT
                    if (block == 1) {
                        xp = (int)(-m.player.worldPosition.X - (m.mouseFollower.X - m.screenWidth) + (x * m.blockSize));
                        yp = (int)(-m.player.worldPosition.Y - (m.mouseFollower.Y - m.screenHeight) + (y * m.blockSize));

                        sb.Draw(m.wall, new Rectangle(xp, yp, m.blockSize, m.blockSize), Color.White);

                    }
                }
            }
        }




        private void drawShadows(Master m, PrimitiveBatch pb) {
            int xp = 0;
            int yp = 0;

            Vector2 compare = new Vector2(-1f, -1f);
            Color c1 = new Color(0f, 0f, 0f, 1.0f);
            Color c2 = new Color(0f, 0f, 0f, .7f);

            Color c = new Color(0f, 0f, 0f, 1.0f);

            lock (m.shadows) {
                foreach (Vector2[] vectors in m.shadows) {
                    lock (vectors) {
                        pb.Begin(PrimitiveType.TriangleList);

                        for (int i = 0; i < 3; i++) {
                            xp = (int)(-m.player.worldPosition.X - (m.mouseFollower.X - m.screenWidth) + (vectors[i].X));
                            yp = (int)(-m.player.worldPosition.Y - (m.mouseFollower.Y - m.screenHeight) + (vectors[i].Y));
                            if (i == 2)
                                pb.AddVertex(new Vector2(xp, yp), c);
                            else
                                pb.AddVertex(new Vector2(xp, yp), c);

                        }


                        pb.End();
                    }
                }

            }

        }







        //FPS counting - for debugging
        private void FPS(Master m) {
            if (System.Environment.TickCount - m.lastTick >= 1000) {
                m.lastFrameRate = m.frameRate;
                m.frameRate = 0;
                m.lastTick = System.Environment.TickCount;
            }
            m.frameRate++;
            m.FPS = m.lastFrameRate;
        }
    }
}
